package com.fankai.lease.web.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fankai.lease.common.constant.RedisConstant;
import com.fankai.lease.model.entity.*;
import com.fankai.lease.model.enums.ItemType;
import com.fankai.lease.web.admin.mapper.*;
import com.fankai.lease.web.admin.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fankai.lease.web.admin.vo.attr.AttrValueVo;
import com.fankai.lease.web.admin.vo.graph.GraphVo;
import com.fankai.lease.web.admin.vo.room.RoomDetailVo;
import com.fankai.lease.web.admin.vo.room.RoomItemVo;
import com.fankai.lease.web.admin.vo.room.RoomQueryVo;
import com.fankai.lease.web.admin.vo.room.RoomSubmitVo;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author liubo
 * @description 针对表【room_info(房间信息表)】的数据库操作Service实现
 * @createDate 2023-07-24 15:48:00
 */
@Service
public class RoomInfoServiceImpl extends ServiceImpl<RoomInfoMapper, RoomInfo>
        implements RoomInfoService {
    @Resource
    private GraphInfoService graphInfoService;
    @Resource
    private RoomAttrValueService roomAttrValueService;

    @Resource
    private RoomFacilityService roomFacilityService;

    @Resource
    private RoomLabelService roomLabelService;

    @Resource
    private RoomLeaseTermService roomLeaseTermService;

    @Resource
    private RoomPaymentTypeServiceImpl roomPaymentTypeService;

    @Resource
    private RoomInfoMapper roomInfoMapper;
    @Resource
    private ApartmentInfoMapper apartmentInfoMapper;

    @Resource
    private AttrValueService attrValueService;
    @Resource
    private AttrKeyService attrKeyService;

    @Resource
    private FacilityInfoMapper facilityInfoMapper;

    @Resource
    private LabelInfoMapper labelInfoMapper;

    @Resource
    private LeaseTermMapper leaseTermMapper;
    @Resource
    private PaymentTypeMapper paymentTypeMapper;

    @Resource
    private RedisTemplate redisTemplate;

    @Override
    @Transactional
    public void saveOrUpdateRoom(RoomSubmitVo roomSubmitVo) {
        Long id = roomSubmitVo.getId();
        if (id != null) {
            updateById(roomSubmitVo);


//            @Schema(description = "图片列表")
            LambdaQueryWrapper<GraphInfo> graphVoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            graphVoLambdaQueryWrapper.eq(GraphInfo::getItemId, id)
                    .eq(GraphInfo::getItemType, ItemType.ROOM);
            graphInfoService.remove(graphVoLambdaQueryWrapper);
            List<GraphVo> graphVoList = roomSubmitVo.getGraphVoList();
            ArrayList<GraphInfo> graphInfoArrayList = new ArrayList<>();
            graphVoList.forEach(graphVo -> {
                GraphInfo graphInfo = new GraphInfo();
                graphInfo.setItemId(id);
                graphInfo.setName(graphVo.getName());
                graphInfo.setUrl(graphVo.getUrl());
                graphInfo.setItemType(ItemType.ROOM);
                graphInfoArrayList.add(graphInfo);
            });
            graphInfoService.saveBatch(graphInfoArrayList);


//            @Schema(description = "属性信息列表")
            LambdaQueryWrapper<RoomAttrValue> roomAttrValueLambdaQueryWrapper = new LambdaQueryWrapper<>();
            roomAttrValueLambdaQueryWrapper.eq(RoomAttrValue::getRoomId, id);

            roomAttrValueService.remove(roomAttrValueLambdaQueryWrapper);


            List<Long> roomSubmitVoAttrValueIds = roomSubmitVo.getAttrValueIds();

            ArrayList<RoomAttrValue> roomAttrValueArrayList = new ArrayList<>();

            roomSubmitVoAttrValueIds.forEach(attrValueId -> {
                RoomAttrValue roomAttrValue = new RoomAttrValue();
                roomAttrValue.setRoomId(id);
                roomAttrValue.setAttrValueId(attrValueId);
                roomAttrValueArrayList.add(roomAttrValue);
            });
            roomAttrValueService.saveBatch(roomAttrValueArrayList);

//            @Schema(description = "配套信息列表")
            LambdaQueryWrapper<RoomFacility> roomFacilityLambdaQueryWrapper = new LambdaQueryWrapper<>();
            roomFacilityLambdaQueryWrapper.eq(RoomFacility::getRoomId, id);

            roomFacilityService.remove(roomFacilityLambdaQueryWrapper);

            List<Long> facilityInfoIds = roomSubmitVo.getFacilityInfoIds();

            ArrayList<RoomFacility> roomFacilityArrayList = new ArrayList<>();

            facilityInfoIds.forEach(facilityInfoId -> {
                RoomFacility roomFacility = new RoomFacility();
                roomFacility.setRoomId(id);
                roomFacility.setFacilityId(facilityInfoId);
                roomFacilityArrayList.add(roomFacility);
            });
            roomFacilityService.saveBatch(roomFacilityArrayList);


//
//            @Schema(description = "标签信息列表")

            LambdaQueryWrapper<RoomLabel> roomLabelLambdaQueryWrapper = new LambdaQueryWrapper<>();
            roomLabelLambdaQueryWrapper.eq(RoomLabel::getRoomId, id);

            roomLabelService.remove(roomLabelLambdaQueryWrapper);

            List<Long> labelInfoIds = roomSubmitVo.getLabelInfoIds();

            ArrayList<RoomLabel> roomLabelArrayList = new ArrayList<>();

            labelInfoIds.forEach(labelInfoId -> {
                RoomLabel roomLabel = new RoomLabel();
                roomLabel.setRoomId(id);
                roomLabel.setLabelId(labelInfoId);
                roomLabelArrayList.add(roomLabel);
            });
            roomLabelService.saveBatch(roomLabelArrayList);

//            @Schema(description = "支付方式列表")

            LambdaQueryWrapper<RoomLeaseTerm> roomLeaseTermLambdaQueryWrapper = new LambdaQueryWrapper<>();
            roomLeaseTermLambdaQueryWrapper.eq(RoomLeaseTerm::getRoomId, id);

            roomLeaseTermService.remove(roomLeaseTermLambdaQueryWrapper);

            List<Long> leaseTermIds = roomSubmitVo.getLeaseTermIds();

            ArrayList<RoomLeaseTerm> roomLeaseTermArrayList = new ArrayList<>();

            leaseTermIds.forEach(leaseTermId -> {
                RoomLeaseTerm roomLeaseTerm = new RoomLeaseTerm();
                roomLeaseTerm.setRoomId(id);
                roomLeaseTerm.setLeaseTermId(leaseTermId);
                roomLeaseTermArrayList.add(roomLeaseTerm);
            });
            roomLeaseTermService.saveBatch(roomLeaseTermArrayList);

//            @Schema(description = "可选租期列表")

            LambdaQueryWrapper<RoomPaymentType> roomPaymentTypeLambdaQueryWrapper = new LambdaQueryWrapper<>();
            roomPaymentTypeLambdaQueryWrapper.eq(RoomPaymentType::getRoomId, id);

            roomPaymentTypeService.remove(roomPaymentTypeLambdaQueryWrapper);

            List<Long> paymentTypeIds = roomSubmitVo.getPaymentTypeIds();

            ArrayList<RoomPaymentType> roomPaymentTypeArrayList = new ArrayList<>();

            paymentTypeIds.forEach(paymentTypeId -> {
                RoomPaymentType roomPaymentType = new RoomPaymentType();
                roomPaymentType.setRoomId(id);
                roomPaymentType.setPaymentTypeId(paymentTypeId);
                roomPaymentTypeArrayList.add(roomPaymentType);
            });
            roomPaymentTypeService.saveBatch(roomPaymentTypeArrayList);
            Boolean delete = redisTemplate.delete(RedisConstant.APP_ROOM_PREFIX + id);
            System.out.println(delete);
        } else {
            save(roomSubmitVo);
        }
    }

    @Override
    public IPage<RoomItemVo> pageRoomItemByQuery(Page<RoomItemVo> page, RoomQueryVo queryVo) {
        return roomInfoMapper.pageRoomItemByQuery(page, queryVo);
    }

    @Override
    public RoomDetailVo getRoomDetailById(Long id) {
        RoomDetailVo roomDetailVo = new RoomDetailVo();
        RoomInfo roomInfo = roomInfoMapper.selectById(id);
        if (roomInfo != null) {
            BeanUtils.copyProperties(roomInfo,roomDetailVo);
            Long apartmentId = roomInfo.getApartmentId();
            ApartmentInfo apartmentInfo = apartmentInfoMapper.selectById(apartmentId);
            roomDetailVo.setApartmentInfo(apartmentInfo);


            LambdaQueryWrapper<GraphInfo> graphInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();

            graphInfoLambdaQueryWrapper.eq(GraphInfo::getItemId, id)
                    .eq(GraphInfo::getItemType, ItemType.ROOM);

            List<GraphInfo> graphInfoList = graphInfoService.list(graphInfoLambdaQueryWrapper);
            ArrayList<GraphVo> graphVoArrayList = new ArrayList<>();
            graphInfoList.forEach(graphInfo -> {
                GraphVo graphVo = new GraphVo();
                BeanUtils.copyProperties(graphInfo, graphVo);
                graphVoArrayList.add(graphVo);
            });
            roomDetailVo.setGraphVoList(graphVoArrayList);


            LambdaQueryWrapper<RoomAttrValue> roomAttrValueLambdaQueryWrapper = new LambdaQueryWrapper<>();
            roomAttrValueLambdaQueryWrapper.eq(RoomAttrValue::getRoomId, id)
                    .eq(RoomAttrValue::getIsDeleted, 0);

            List<RoomAttrValue> roomAttrValueList = roomAttrValueService.list(roomAttrValueLambdaQueryWrapper);
            List<Long> attrValueIdsList = roomAttrValueList.stream().map(RoomAttrValue::getAttrValueId).toList();

            if (!attrValueIdsList.isEmpty()) {
                LambdaQueryWrapper<AttrValue> attrValueVoLambdaQueryWrapper = new LambdaQueryWrapper<>();

                attrValueVoLambdaQueryWrapper.in(AttrValue::getId, attrValueIdsList)
                        .eq(AttrValue::getIsDeleted, 0);

                List<AttrValue> attrValueList = attrValueService.list(attrValueVoLambdaQueryWrapper);
                ArrayList<AttrValueVo> attrValueVoArrayList = new ArrayList<>();

                attrValueList.forEach(attrValue -> {
                    AttrValueVo attrValueVo = new AttrValueVo();
                    BeanUtils.copyProperties(attrValue, attrValueVo);
                    LambdaQueryWrapper<AttrKey> attrKeyLambdaQueryWrapper = new LambdaQueryWrapper<>();
                    attrKeyLambdaQueryWrapper.eq(AttrKey::getId, attrValue.getAttrKeyId())
                            .eq(AttrKey::getIsDeleted, 0);
                    AttrKey attrKey = attrKeyService.getOne(attrKeyLambdaQueryWrapper);
                    if (attrKey != null) {
                        attrValueVo.setAttrKeyName(attrKey.getName());
                    }
                    attrValueVoArrayList.add(attrValueVo);
                });
                roomDetailVo.setAttrValueVoList(attrValueVoArrayList);
            }


            LambdaQueryWrapper<RoomFacility> roomFacilityLambdaQueryWrapper = new LambdaQueryWrapper<>();
            roomFacilityLambdaQueryWrapper.eq(RoomFacility::getRoomId, id)
                    .eq(RoomFacility::getIsDeleted, 0);
            List<RoomFacility> roomFacilityList = roomFacilityService.list(roomFacilityLambdaQueryWrapper);
            List<Long> facilityIds = roomFacilityList.stream().map(RoomFacility::getFacilityId).toList();
            if (!facilityIds.isEmpty()) {
                LambdaQueryWrapper<FacilityInfo> facilityInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                facilityInfoLambdaQueryWrapper.in(FacilityInfo::getId, facilityIds)
                        .eq(FacilityInfo::getIsDeleted, 0);
                List<FacilityInfo> facilityInfoList = facilityInfoMapper.selectList(facilityInfoLambdaQueryWrapper);
                roomDetailVo.setFacilityInfoList(facilityInfoList);
            }


            LambdaQueryWrapper<RoomLabel> labelLambdaQueryWrapper = new LambdaQueryWrapper<>();

            labelLambdaQueryWrapper.eq(RoomLabel::getRoomId, id)
                    .eq(RoomLabel::getIsDeleted, 0);

            List<RoomLabel> roomLabelList = roomLabelService.list(labelLambdaQueryWrapper);
            List<Long> labelIds = roomLabelList.stream().map(RoomLabel::getLabelId).toList();

            if (!labelIds.isEmpty()) {
                LambdaQueryWrapper<LabelInfo> labelInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();

                labelInfoLambdaQueryWrapper.in(LabelInfo::getId, labelIds)
                        .eq(LabelInfo::getIsDeleted, 0);

                List<LabelInfo> labelInfoList = labelInfoMapper.selectList(labelInfoLambdaQueryWrapper);
                roomDetailVo.setLabelInfoList(labelInfoList);
            }


            LambdaQueryWrapper<RoomPaymentType> roomPaymentTypeLambdaQueryWrapper = new LambdaQueryWrapper<>();

            List<RoomPaymentType> roomPaymentTypeList = roomPaymentTypeService.list(roomPaymentTypeLambdaQueryWrapper);

            List<Long> paymentTypeIds = roomPaymentTypeList.stream().map(RoomPaymentType::getPaymentTypeId).toList();
            if (!paymentTypeIds.isEmpty()) {
                LambdaQueryWrapper<PaymentType> paymentTypeLambdaQueryWrapper = new LambdaQueryWrapper<>();
                paymentTypeLambdaQueryWrapper.in(PaymentType::getId, paymentTypeIds);
                List<PaymentType> paymentTypeList = paymentTypeMapper.selectList(paymentTypeLambdaQueryWrapper);
                roomDetailVo.setPaymentTypeList(paymentTypeList);
            }

            LambdaQueryWrapper<RoomLeaseTerm> roomLeaseTermLambdaQueryWrapper = new LambdaQueryWrapper<>();

            roomLeaseTermLambdaQueryWrapper.eq(RoomLeaseTerm::getRoomId, id)
                    .eq(RoomLeaseTerm::getIsDeleted, 0);

            List<RoomLeaseTerm> roomLeaseTermList = roomLeaseTermService.list(roomLeaseTermLambdaQueryWrapper);


            List<Long> roomLeaseTermIds = roomLeaseTermList.stream().map(RoomLeaseTerm::getLeaseTermId).toList();

            if (!roomLeaseTermIds.isEmpty()) {
                LambdaQueryWrapper<LeaseTerm> labelInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();

                labelInfoLambdaQueryWrapper.in(LeaseTerm::getId, roomLeaseTermIds)
                        .eq(LeaseTerm::getIsDeleted, 0);

                List<LeaseTerm> leaseTermList = leaseTermMapper.selectList(labelInfoLambdaQueryWrapper);
                roomDetailVo.setLeaseTermList(leaseTermList);
            }
        }
        return roomDetailVo;
    }

    @Override
    @Transactional
    public void removeRoomById(Long id) {
        roomInfoMapper.deleteById(id);

        //2.删除graphInfoList
        LambdaQueryWrapper<GraphInfo> graphQueryWrapper = new LambdaQueryWrapper<>();
        graphQueryWrapper.eq(GraphInfo::getItemType, ItemType.ROOM);
        graphQueryWrapper.eq(GraphInfo::getItemId, id);
        graphInfoService.remove(graphQueryWrapper);

        //3.删除attrValueList
        LambdaQueryWrapper<RoomAttrValue> attrQueryWrapper = new LambdaQueryWrapper<>();
        attrQueryWrapper.eq(RoomAttrValue::getRoomId, id);
        roomAttrValueService.remove(attrQueryWrapper);

        //4.删除facilityInfoList
        LambdaQueryWrapper<RoomFacility> facilityQueryWrapper = new LambdaQueryWrapper<>();
        facilityQueryWrapper.eq(RoomFacility::getRoomId, id);
        roomFacilityService.remove(facilityQueryWrapper);

        //5.删除labelInfoList
        LambdaQueryWrapper<RoomLabel> labelQueryWrapper = new LambdaQueryWrapper<>();
        labelQueryWrapper.eq(RoomLabel::getRoomId, id);
        roomLabelService.remove(labelQueryWrapper);

        //6.删除paymentTypeList
        LambdaQueryWrapper<RoomPaymentType> paymentQueryWrapper = new LambdaQueryWrapper<>();
        paymentQueryWrapper.eq(RoomPaymentType::getRoomId, id);
        roomPaymentTypeService.remove(paymentQueryWrapper);

        //7.删除leaseTermList
        LambdaQueryWrapper<RoomLeaseTerm> termQueryWrapper = new LambdaQueryWrapper<>();
        termQueryWrapper.eq(RoomLeaseTerm::getRoomId, id);
        roomLeaseTermService.remove(termQueryWrapper);



    }
}




